/*******************************************************************************************
 * Copyright (c) 2006-2009 Alex Robson, Rob Simmons, Craig Israel, and Rachel Twyford
 *
 * Use of this software in any form requires that you have both 
 * read and agreed to the following terms:
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions: 
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, 
 * this list of conditions and the following disclaimer in the 
 * documentation and/or other materials provided with the distribution.
 * Neither the name of Nvigorate nor the names of its contributors may 
 * be used to endorse or promote products derived from this software without 
 * specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************************/

using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Collections;
using System.Collections.Generic;

namespace Nvigorate.Data
{
    /// <summary>
    /// Summary description for Procedure.
    /// </summary>
    internal class Procedure : DatabaseCommand
    {
        #region Members
        private string _procedureName = "";
        #endregion

        #region Properties

        public string ProcedureName
        {
            get { return _procedureName; }
        }

        #endregion

        #region Private	Methods

        private void ProcessArguments(DataTable parameters)
        {
            foreach (DataRow row in parameters.Rows)
            {
                ParameterDirection direction = ParameterDirection.Input;

                if (row["Parameter_Mode"].ToString() == "OUT")
                {
                    direction = ParameterDirection.Output;
                }
                else if (row["Parameter_Mode"].ToString() == "INOUT")
                {
                    direction = ParameterDirection.InputOutput;
                }

                IDbDataParameter parameter =
                    _provider.GetParameter(row["Parameter_Name"].ToString(), DBNull.Value, row["Data_Type"].ToString(), direction);

                _command.Parameters.Add(parameter);
            }
        }

        private void ProcessArguments(DataRow[] parameters)
        {
            foreach (DataRow row in parameters)
            {
                ParameterDirection direction = ParameterDirection.Input;

                if (row["Parameter_Mode"].ToString() == "OUT")
                {
                    direction = ParameterDirection.Output;
                }
                else if (row["Parameter_Mode"].ToString() == "INOUT")
                {
                    direction = ParameterDirection.InputOutput;
                }

                IDbDataParameter parameter =
                    _provider.GetParameter(row["Parameter_Name"].ToString(), DBNull.Value, row["Data_Type"].ToString(), direction);

                _command.Parameters.Add(parameter);
            }
        }
        public override void SetParameters(Dictionary<string, object> parameters)
        {
            foreach (var pair in parameters)
            {
                _command.Parameters[pair.Key] = pair.Value;
            }
        }

        #endregion

        #region Constructors

        internal Procedure(string procedureName, IDatabaseProvider provider, int timeout, DataTable parameters) : base(procedureName, provider)
        {
            _procedureName = procedureName;
            _command.CommandType = CommandType.StoredProcedure;
            _command.CommandTimeout = timeout;
            

            if (parameters != null)
            {
                if (parameters.Rows.Count > 0)
                {
                    ProcessArguments(parameters);
                }
            }
        }

        internal Procedure(string procedureName, IDatabaseProvider provider, int timeout, DataRow[] parameters) : base(procedureName, provider)
        {
            _procedureName = procedureName;
            _command.CommandType = CommandType.StoredProcedure;
            _command.CommandTimeout = timeout; 

            if (parameters != null)
            {
                if (parameters.Length > 0)
                {
                    ProcessArguments(parameters);
                }
            }
        }

        internal Procedure(string procedureName, IDatabaseProvider provider, int timeout, IEnumerable<IDbDataParameter> parameters) : base(procedureName, provider, parameters)
        {
            _procedureName = procedureName;
            _command.CommandType = CommandType.StoredProcedure;
            _command.CommandTimeout = timeout;
        }

        #endregion
    }
}